
/**
 * JWE的标准格式内容
 * The JWE Compact Serialization represents encrypted content as a compact, URL-safe string. This string is:
 * 
 * BASE64URL(UTF8(JWE Protected Header)) || '.' ||
 * BASE64URL(JWE Encrypted Key) || '.' ||
 * BASE64URL(JWE Initialization Vector) || '.' ||
 * BASE64URL(JWE Ciphertext) || '.' ||
 * BASE64URL(JWE Authentication Tag)
 * 
 */

const crypto = require('crypto')
const fs = require('fs')
const base64url = require('base64-url')
const test = require('./jwetest')






// 读取公钥,私钥文件内容
let publicKeyStr = fs.readFileSync("./rsa-pub.pem","utf8")

const appId = 'APPID001'

let jsonData = {
    firstName: 'Ainge',
    appId: appId,
    data : {
        username: 'AingeZhu',
        password: 'password'
    }
}

var header = {
    "enc":"A128GCM",
    "alg":"RSA-OAEP"
}
let headerBase64 = base64url.encode(JSON.stringify(header))

//随机产生加密原文的对称密钥cek
let cek = crypto.randomBytes(16)

//加密cek，cek需要加密后才能传输
let cek_enc = crypto.publicEncrypt({key:publicKeyStr,padding: crypto.constants.RSA_PKCS1_OAEP_PADDING}, cek);
const cekBase64 = cek_enc.toString('base64')
console.log("cekBase64= " + cekBase64)

// 产生iv向量
let iv = crypto.randomBytes(12)
const ivBase64 = iv.toString('base64')
console.log("ivBase64="+ivBase64)

// 使用AES-128-GCM进行加密
let cipher = crypto.createCipheriv('aes-128-gcm',cek,iv,{authTagLength: 16})

// 标准规范是需要这个AdditionalAuthenticatedData的，就是Baes64Url(header)转ASCII码
// var aad = ascii.toASCII(headerBase64);
cipher.setAAD(Buffer.from(headerBase64,"ascii"))
let ciphertext = cipher.update(JSON.stringify(jsonData),'utf8')
cipher.final()

let tag = cipher.getAuthTag()



// 打印
const ciphertextBase64 = ciphertext.toString('base64')
console.log("ciphertextBase64=" + ciphertextBase64)
const tagBase64 = tag.toString('base64')
console.log("tagBase64=" + tagBase64)


console.log('+++++++++++++++++++++++++++++++++post请求到服务器的数据+++++++++++++++++++++++++++++++++++')
let jweToken = JWEUtil.format(headerBase64,cekBase64,ivBase64,ciphertextBase64,tagBase64)
// 将base64转为base64url
console.log(base64url.escape(jweToken))
console.log('+++++++++++++++++++++++++++++++++post请求到服务器的数据+++++++++++++++++++++++++++++++++++')


// 验证一下
const res = test.verify(header,cek_enc,iv,ciphertext,tag)
console.log(res)
